#include "task_main.h"
#include <stdio.h>
#include <stdarg.h>
#include "strutil.hpp"
#include "stimer.h"
#include "zh_iSwitch.h"
#include "adc.h"
#include "log.h"
#include "bsp_protocol.hpp"
#include "wifi_connect.hpp"
#include "music_module.h"
#include "servo.h"
#include "at_aithinker_combo.h"
#include "smartlock.h"
#include "sharpiot.h"
#include "bsp_flash_config.h"

#define debug_printf(str, ...) UARTx_Printf(&huart1, str, ##__VA_ARGS__)
#define TASK_BUFFER_SIZE 8

stimer_task_t task_buffer[TASK_BUFFER_SIZE];
uint16_t TaskInputID, TaskOutputID, TaskMsgHandleID, TaskDisplayID, TaskATComboID;
SmartLock smartlock;
AT_AiCombo aiwb2(at_send_data);
wifiConnect wifiJAP(&aiwb2);
extern uint16_t ADC1Buf[ADC1_BUF_SIZE];


void user_task_init(void)
{
    stimer_init(task_buffer, TASK_BUFFER_SIZE);
    TaskOutputID = stimer_create_task(TaskOutput, 10, 2, 1);
    TaskDisplayID = stimer_create_task(TaskDisplay, 100, 0, 1);
    TaskBuzzerID = stimer_create_task(TaskBuzzer, 50, 1, 1);
    TaskATComboID = stimer_create_task(TaskATCombo, 10, 1, 1);
}

/**
 * @brief 首次初始化进行参数配置(出厂设置)
 */
void bsp_flash_config_first_init(void)
{
    /* 这里添加第一次启动的初始化值 */
    #if 1
    // 锁参数配置
    sysCfgInfo.openLockAngle = smartlock.openLockAngle;
    sysCfgInfo.autoCloseTime = smartlock.autoCloseTime;
    // wifi 初始参数配置
    memcpy(sysCfgInfo.wifi_ssid, "TP-LINK_405", 12);
    memcpy(sysCfgInfo.wifi_pwd, "1234567890", 11);
    sysCfgInfo.wifi_bssid[0] = '\0';
    // mqtt 初始参数配置
    sysCfgInfo.mqtt_id_openLockAngle = aiwb2.mqtt_cfg->topicsub[0].id;
    sysCfgInfo.mqtt_id_autoCloseTime = aiwb2.mqtt_cfg->topicsub[1].id;
    sysCfgInfo.mqtt_id_lockCtrl = aiwb2.mqtt_cfg->topicsub[2].id;
    memcpy(sysCfgInfo.mqtt_client_id, aiwb2.mqtt_cfg->client_id, strlen(aiwb2.mqtt_cfg->client_id)+1);
    memcpy(sysCfgInfo.mqtt_username, aiwb2.mqtt_cfg->username, strlen(aiwb2.mqtt_cfg->username)+1);
    memcpy(sysCfgInfo.mqtt_password, aiwb2.mqtt_cfg->password, strlen(aiwb2.mqtt_cfg->password)+1);
    #endif
    /* ---------结束添加------- */
}

/**
 * @brief 从非易失性存储器读取系统配置信息，并进行初始化
 */
void user_config_init(void)
{
	bsp_flash_config_init(); // 将flash中的配置信息读出到sysCfgInfo中
    #if 1
	smartlock.openLockAngle = sysCfgInfo.openLockAngle;
	smartlock.autoCloseTime = sysCfgInfo.autoCloseTime;
    user_mqtt_cfg.topicsub[0].id = sysCfgInfo.mqtt_id_openLockAngle;
    user_mqtt_cfg.topicsub[1].id = sysCfgInfo.mqtt_id_autoCloseTime;
    user_mqtt_cfg.topicsub[2].id = sysCfgInfo.mqtt_id_lockCtrl;
    user_mqtt_cfg.client_id = sysCfgInfo.mqtt_client_id;
    user_mqtt_cfg.username = sysCfgInfo.mqtt_username;
    user_mqtt_cfg.password = sysCfgInfo.mqtt_password;
    debug_printf("openLockAngle: <%f>\r\nautoCloseTime: <%d>\r\nwifi_ssid: <%s>\r\nwifi_pwd: <%s>\r\n",
                  sysCfgInfo.openLockAngle, sysCfgInfo.autoCloseTime,
                  sysCfgInfo.wifi_ssid, sysCfgInfo.wifi_pwd);
    debug_printf("mqtt_id_openLockAngle: <%d>\r\nmqtt_id_autoCloseTime: <%d>\r\nmqtt_id_lockCtrl: <%d>\r\n",
                  sysCfgInfo.mqtt_id_openLockAngle,
                  sysCfgInfo.mqtt_id_autoCloseTime,
                  sysCfgInfo.mqtt_id_lockCtrl);
                
    debug_printf("mqtt_client_id: <%s>\r\nmqtt_username: <%s>\r\nmqtt_password: <%s>\r\n",
                  sysCfgInfo.mqtt_client_id,
                  sysCfgInfo.mqtt_username,
                  sysCfgInfo.mqtt_password);
    #endif
    debug_printf("----------------------------------------------\r\n");
}

/* USER CODE BEGIN Header_TaskInit */
/**
 * @brief  Function implementing the InitTask thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_TaskInit */
void TaskInit(void const *argument)
{
    /* USER CODE BEGIN TaskInit */
    log_set_level(LOG_LEVEL_NONE);
    board_base_init(); // UART, TIM, LED
    user_task_init();
	user_config_init();
    servo1.init();
    smartlock.setLockState(0); // 锁初始状态为关闭
    music_module_init();
    BSP_POWER_ENABLE();
    HAL_Delay(50);
    BSP_WIFI_ENABLE();
    smartlock.setLedState(2);
    wifiJAP.start_connect(sysCfgInfo.wifi_ssid, sysCfgInfo.wifi_pwd, sysCfgInfo.wifi_bssid);
    Beep(200);
    
    stimer_task_delay_start(TaskOutputID, STIMER_TASK_LOOP, (void *)"TaskOutput", 5);
    stimer_task_delay_start(TaskDisplayID, STIMER_TASK_LOOP, (void *)"TaskDisplay", 20);
    stimer_task_delay_start(TaskATComboID, STIMER_TASK_LOOP, (void *)"TaskATCombo", 2000);
    /* USER CODE END TaskInit */
}

/* USER CODE BEGIN Header_TaskInput */
/**
 * @brief  Function implementing the InputTask thread.
 * @param  argument: Not used
 * @retval None
 */
/* USER CODE END Header_TaskInput */
void TaskInput(void const *argument)
{
    /* USER CODE BEGIN TaskInput */
    /* Infinite loop */
    //	uint32_t Key_Input = 0;
    //	Key_Input |= KEYx_Read(KEY0, 0);
    //	Key_Input |= KEYx_Read(KEY1, 1);
    //	Key_Value = iSWx_Handler(Key_Input);

    /* USER CODE END TaskInput */
}

void TaskATCombo(void const *argument)
{
    aiwb2.tick(10);
}
void TaskDisplay(void const *argument)
{
    /* USER CODE BEGIN TaskDisplay */
    /* Infinite loop */

    /* USER CODE END TaskDisplay */
}

static void led_blink_end_task(void const *arg)
{
    uint32_t id = (int)arg;
    if (id == 1)
        LEDx_Write(LED1, 0);
}
void led_blink(uint32_t id, uint32_t ms)
{
    if (id == 1)
        LEDx_Write(LED1, 1);
    else
        return;
    stimer_task_oneshot(led_blink_end_task, ms, 0, (int*)id);
}
/* USER CODE BEGIN Header_TaskOutput */
/**
 * @brief Function implementing the OutputTask thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_TaskOutput */
void TaskOutput(void const *argument)
{
    /* USER CODE BEGIN TaskOutput */
    /* Infinite loop */
    static uint32_t cnt = 0;
    cnt++;
    if (cnt % 50 == 0) // 500ms
    {

        cnt = 0;
        // HAL_PWR_EnterSLEEPMode();
        switch (smartlock.ledState)
        {
        case 0:
            LEDx_Write(LED1, 0);
            break;
        case 1:
            LEDx_Write(LED1, 1);
            break;
        case 2:
            LEDx_Togger(LED1);
            break;
        case 3:
            led_blink(1, 100);
						break;
        default:
            smartlock.ledState = 0;
            break;
        }
    }
    /* USER CODE END TaskOutput */
}

#if 1
/* USER CODE BEGIN Header_TaskMsgHandle */
/**
 * @brief Function implementing the MsgHandlerTask thread.
 * @param argument: Not used
 * @retval None
 */
/* USER CODE END Header_TaskMsgHandle */
void TaskMsgHandle(void const *argument)
{
    /* USER CODE BEGIN Task_MsgHandle */
    uint8_t *pdata = NULL;
    UART_HandleTypeDef *phuart = NULL;
    uint32_t size = 0;
    //    uint32_t taskNotify;
    //    TickType_t state;
    //	  uint8_t buff[128];

    /* Infinite loop */

    //        state = xTaskNotifyWait(0xffffffffUL,
    //                                0,
    //                                &taskNotify,
    //                                portMAX_DELAY);

    // 获取任务通知值并清空
    if (hrx1.rxCpltFlag) /* 读到了数据 */
    {
        hrx1.rxCpltFlag = 0;
        phuart = &huart1;
        pdata = UART_GetRxData(&hrx1);
        size = UART_GetRxSize(&hrx1);

        // UARTx_Printn(&huart1, (uint8_t*)"[RX1]", 5);
        // UARTx_Printn(&huart1, pdata, size);
        // UARTx_Printn(&huart1, (uint8_t*)"\r\n", 2);

        if (size > 3 && pdata[0] == 'A' && pdata[1] == 'T')
        {
            UARTx_Printn(&huart3, pdata, size);
        }
    }
    if (hrx2.rxCpltFlag) /* 读到了数据 */
    {
        hrx2.rxCpltFlag = 0;
        phuart = &huart2;
        pdata = UART_GetRxData(&hrx2);
        size = UART_GetRxSize(&hrx2);
        UARTx_Printn(&huart1, (uint8_t *)"[RX2]", 5);
        UARTx_Printn(&huart1, pdata, size);
        UARTx_Printn(&huart1, (uint8_t *)"\r\n", 2);
        // 转发回去
        // UARTx_Printn(&huart2, pdata, size);
    }
    if (hrx3.rxCpltFlag) /* 读到了数据 */
    {
        hrx3.rxCpltFlag = 0;
        phuart = &huart3;
        pdata = UART_GetRxData(&hrx3);
        size = UART_GetRxSize(&hrx3);
        // UARTx_Printn(&huart1, (uint8_t *)"[RX3]", 5);
        UARTx_Printn(&huart1, pdata, size);
        // UARTx_Printn(&huart1, (uint8_t *)"\r\n", 2);
        if (size)
            aiwb2.receive_handle(pdata, size);
    }

    if (size != 0)
    {
        SYS_CMD(phuart, pdata, size);
    }

    /* USER CODE END Task_MsgHandle */
}

#endif

/**
 * @brief  Conversion complete callback in non blocking mode
 * @param  hadc ADC handle
 * @retval None
 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    uint16_t ADCValue = 0;
    for (size_t i = 0; i < ADC1_BUF_SIZE; i++)
    {
        ADCValue += ADC1Buf[i];
    }
    // V1:V2 = 10:1 ,smartlock.vbat = V1 + V2 = V2 + 10*V2 = 11*V2;
    smartlock.vbat = (ADCValue / ADC1_BUF_SIZE * 3.3f / 4095) * 11.0f;
    // HAL_ADC_Stop_DMA(hadc);//停止ADC电压采集
    // BSP_smartlock.vbat_ADC_DISABLE();
}



void user_subscribe_callback(uint16_t id, const uint8_t *pPayload, uint16_t len)
{
    SharpIotPack pack(pPayload, len); // 解析数据包，得到pid和timestamp

    if (pack.pid == sysCfgInfo.mqtt_id_openLockAngle)
    {
        smartlock.openLockAngle = pack.getFloat();
		sysCfgInfo.openLockAngle = smartlock.openLockAngle;
		bsp_flash_config_save_start();
        UARTx_Printf(&huart1, "[smartlock] set openLockAngle:%.2f\r\n", pack.getFloat());
    }
    else if (pack.pid == sysCfgInfo.mqtt_id_autoCloseTime)
    {
        smartlock.autoCloseTime = pack.getInt();
		sysCfgInfo.autoCloseTime = smartlock.autoCloseTime;
		bsp_flash_config_save_start();
        UARTx_Printf(&huart1, "[smartlock] set autoCloseTime:%d\r\n", pack.getInt());
    }
    else if (pack.pid == sysCfgInfo.mqtt_id_lockCtrl)
    {
        smartlock.setLockState(pack.getBool());
        UARTx_Printf(&huart1, "[smartlock] set lock state:%s\r\n", 
                     (pack.getBool() ? "Open":"Close"));
        if (smartlock.isLocked)
        {
            smartlock.setLedState(3); // 上锁状态,短闪
        }
        else
        {
            smartlock.setLedState(1); // 解锁状态,常亮
        }
    }
}
